/**
 * @author mrdoob / http://mrdoob.com/
 * @author alteredq / http://alteredqualia.com/
 * @author paulirish / http://paulirish.com/
 */

FirstPersonControls = function ( object, domElement ) {

	this.object = object;
	this.target = new THREE.Vector3( 0, 0, 0 );

	this.domElement = ( domElement !== undefined ) ? domElement : document;

	this.movementSpeed = 1.0;
	this.lookSpeed = 0.005;

	this.noFly = false;
	this.lookVertical = true;
	this.autoForward = false;

	this.activeLook = true;

	this.heightSpeed = false;
	this.heightCoef = 1.0;
	this.heightMin = 0.0;

	this.constrainVertical = false;
	this.verticalMin = 0;
	this.verticalMax = Math.PI;

	this.autoSpeedFactor = 0.0;

	this.mouseX = 0;
	this.mouseY = 0;

	this.lat = 0;
	this.lon = 0;
	this.phi = 0;
	this.theta = 0;

	this.moveForward = false;
	this.moveBackward = false;
	this.moveLeft = false;
	this.moveRight = false;
	this.freeze = false;
	
	
	/*
	 * add by ben
	 */
	this.debug=false;
	this.rotateLeft=false;
	this.rotateRight=false;
	this.lookLeft=false;
	this.lookRight=false;
	this.lookUp=false;
	this.lookDown=false;
	this.moveForwardFreeze=false;
	this.moveLeftFreeze=false;
	this.moveRightFreeze=false;
	this.moveBackwardFreeze=false;
	
	this.lookOrgin=false;	

	this.targetPosition=new THREE.Vector3(0,200,0);
	/*
	 * end
	 */
	
	

	this.mouseDragOn = false;

	if ( this.domElement === document ) {

		this.viewHalfX = window.innerWidth / 2;
		this.viewHalfY = window.innerHeight / 2;

	} else {

		this.viewHalfX = this.domElement.offsetWidth / 2;
		this.viewHalfY = this.domElement.offsetHeight / 2;
		this.domElement.setAttribute( 'tabindex', -1 );

	}

	this.onMouseDown = function ( event ) {

		if ( this.domElement !== document ) {

			this.domElement.focus();

		}

		event.preventDefault();
		event.stopPropagation();

		if ( this.activeLook ) {

			switch ( event.button ) {

				case 0: this.moveForward = true; break;
				case 2: this.moveBackward = true; break;

			}

		}

		this.mouseDragOn = true;

	};

	this.onMouseUp = function ( event ) {

		event.preventDefault();
		event.stopPropagation();

		if ( this.activeLook ) {

			switch ( event.button ) {

				case 0: this.moveForward = false; break;
				case 2: this.moveBackward = false; break;

			}

		}

		this.mouseDragOn = false;

	};

	this.onMouseMove = function ( event ) {

		if ( this.domElement === document ) {

			this.mouseX = event.pageX - this.viewHalfX;
			this.mouseY = event.pageY - this.viewHalfY;

		} else {

			this.mouseX = event.pageX - this.domElement.offsetLeft - this.viewHalfX;
			this.mouseY = event.pageY - this.domElement.offsetTop - this.viewHalfY;

		}

	};
	
	this.onMouseClick=function(event){
	  this.mouseX=event.pageX;
    this.mouseY=event.pageY;
    alert(this.mouseX+";"+this.mouseY);
	}

	this.onKeyDown = function ( event ) {

		switch( event.keyCode ) {

			case 38: /*up*/
			case 87: /*W*/ this.moveForward = true; break;

			case 37: /*left*/
			case 65: /*A*/ this.moveLeft = true; break;

			case 40: /*down*/
			case 83: /*S*/ this.moveBackward = true; break;

			case 39: /*right*/
			case 68: /*D*/ this.moveRight = true; break;

			case 82: /*R*/ this.moveUp = true; break;
			case 70: /*F*/ this.moveDown = true; break;

			case 81: /*Q*/ this.freeze = !this.freeze; break;
			
			case 13: this.debug=!this.dubug;break;
			
      case 90:/*Z*/ this.rotateLeft=true;break;
      case 67:/*C*/ this.rotateRight=true;break;
      
      case 73:/*I*/ this.lookUp=true;break;
      case 75:/*K*/ this.lookDown=true;break;
      case 74:/*J*/ this.lookLeft=true;break;
      case 76:/*L*/ this.lookRight=true;break;

		}

	};

	this.onKeyUp = function ( event ) {

		switch( event.keyCode ) {

			case 38: /*up*/
			case 87: /*W*/ this.moveForward = false; break;

			case 37: /*left*/
			case 65: /*A*/ this.moveLeft = false; break;

			case 40: /*down*/
			case 83: /*S*/ this.moveBackward = false; break;

			case 39: /*right*/
			case 68: /*D*/ this.moveRight = false; break;

			case 82: /*R*/ this.moveUp = false; break;
			case 70: /*F*/ this.moveDown = false; break;
			
			case 90:/*Z*/ this.rotateLeft=false;break;
			case 67:/*C*/ this.rotateRight=false;break;
			
      case 73:/*I*/ this.lookUp=false;break;
      case 75:/*K*/ this.lookDown=false;break;
      case 74:/*J*/ this.lookLeft=false;break;
      case 76:/*L*/ this.lookRight=false;break;

		}

	};
	
	this.around=function(delta){
	  if(this.lookLeft||this.lookRight||this.lookUp||this.lookDown||this.lookOrgin){
	    this.lookAround(delta);
	  }else if(this.moveForward|| this.moveLeft||this.moveBackward||this.moveRight){
	    this.moveAround(delta);
	  }else if(this.rotateLeft || this.rotateRight){
	    this.rotateAround(delta);
	  }
	}
	
	this.rotateAround = function( delta ) {
    var actualMoveSpeed = 0;
    
    if(this.debug){
      console.warn('debug');
    }
    
    if ( this.freeze ) {
      
      return;
      
    } 

      actualMoveSpeed = delta * this.movementSpeed;

      if ( this.rotateLeft) this.object.translateX( - actualMoveSpeed );
      if ( this.rotateRight) this.object.translateX( actualMoveSpeed );

     this.object.lookAt( this.targetPosition );  

  };

	
	this.moveAround=function(delta){
	  var actualMoveSpeed = 0;
    
    if(this.debug){
      console.warn('debug');
    }

    if ( this.freeze ) {
      
      return;
      
    } 
      actualMoveSpeed = delta * this.movementSpeed;

      if ( this.moveForward && !this.moveForwardFreeze ) {
      	var posY=this.object.position.y;
      	this.object.translateZ( - ( actualMoveSpeed + this.autoSpeedFactor ) );
      	this.object.position.y=posY;
      }
      if ( this.moveBackward && !this.moveBackwardFreeze ) {
      	var posY=this.object.position.y;
      	this.object.translateZ( actualMoveSpeed );
      	this.object.position.y=posY;
      }

      if ( this.moveLeft && !this.moveLeftFreeze ) this.object.translateX( - actualMoveSpeed );
      if ( this.moveRight && !this.moveRightFreeze) this.object.translateX( actualMoveSpeed );
	  
      if ( this.moveUp ) this.object.translateY( actualMoveSpeed );
      if ( this.moveDown ) this.object.translateY( - actualMoveSpeed );

	}
	
	this.lookAround=function(delta){
    var actualMoveSpeed = 0;
    
    if(this.debug){
      console.warn('debug');
    }
      
      if(this.lookLeft)this.mouseX=-1*window.innerWidth;
      if(this.lookRight) this.mouseX=window.innerWidth;
      if(this.lookUp) this.mouseY=-1*window.innerHeight;
      if(this.lookDown) this.mouseY=window.innerHeight;
      // if(this.lookOrgin) {
    	// this.mouseX=0;
    	// this.mouseY=0;
    	// }
    if ( this.freeze ) {
      
      return;
      
    } 
    if(this.lookOrgin){
   		this.lon=-90;this.lat=0;
   		this.object.lookAt(this.object.position);
   		return;
   	}
    var verticalLookRatio = 1;


    
    var actualLookSpeed = delta * this.lookSpeed;

    if( this.lookLeft ||this.lookRight ) this.lon += this.mouseX * actualLookSpeed;
    if( this.lookUp ||this.lookDown ) this.lat -= this.mouseY * actualLookSpeed * verticalLookRatio;
	// if(this.lookOrgin){
		// this.lon=0;
		// this.lat=0;
	// }

    this.lat = Math.max( - 85, Math.min( 85, this.lat ) );
    this.phi = ( 90 - this.lat ) * Math.PI / 180;

    this.theta = this.lon * Math.PI / 180;

        var targetPosition = new THREE.Vector3;
        position = this.object.position;
        // position = this.targetPosition;;
        targetPosition.x = position.x + 100 * Math.sin( this.phi ) * Math.cos( this.theta );
        targetPosition.y = position.y + 100 * Math.cos( this.phi );
        targetPosition.z = position.z + 100 * Math.sin( this.phi ) * Math.sin( this.theta );
        

        
    this.object.lookAt( targetPosition );   

	}

	this.update = function( delta ) {
		var actualMoveSpeed = 0;
		
		if(this.debug){
			console.warn('debug');
		}
	  if(this.lookLeft)this.mouseX=-1*window.innerWidth;
      if(this.lookRight) this.mouseX=window.innerWidth;
      if(this.lookUp) this.mouseY=window.innerHeight;
      if(this.lookDown) this.mouseY=-1*window.innerHeight;
		
		if ( this.freeze ) {
			
			return;
			
		} else {

			if ( this.heightSpeed ) {

				var y = THREE.Math.clamp( this.object.position.y, this.heightMin, this.heightMax );
				var heightDelta = y - this.heightMin;

				this.autoSpeedFactor = delta * ( heightDelta * this.heightCoef );

			} else {

				this.autoSpeedFactor = 0.0;

			}

			actualMoveSpeed = delta * this.movementSpeed;

			if ( this.moveForward || ( this.autoForward && !this.moveBackward ) ) this.object.translateZ( - ( actualMoveSpeed + this.autoSpeedFactor ) );
			if ( this.moveBackward ) this.object.translateZ( actualMoveSpeed );

			if ( this.moveLeft ||this.rotateLeft) this.object.translateX( - actualMoveSpeed );
			if ( this.moveRight || this.rotateRight) this.object.translateX( actualMoveSpeed );

			if ( this.moveUp ) this.object.translateY( actualMoveSpeed );
			if ( this.moveDown ) this.object.translateY( - actualMoveSpeed );
			



			var actualLookSpeed = delta * this.lookSpeed;

			if ( !this.activeLook ) {

				actualLookSpeed = 0;

			}

			this.lon += this.mouseX * actualLookSpeed;
			if( this.lookVertical ) this.lat -= this.mouseY * actualLookSpeed;

			this.lat = Math.max( - 85, Math.min( 85, this.lat ) );
			this.phi = ( 90 - this.lat ) * Math.PI / 180;
			this.theta = this.lon * Math.PI / 180;

			var targetPosition = this.target,
				position = this.object.position;

			targetPosition.x = position.x + 100 * Math.sin( this.phi ) * Math.cos( this.theta );
			targetPosition.y = position.y + 100 * Math.cos( this.phi );
			targetPosition.z = position.z + 100 * Math.sin( this.phi ) * Math.sin( this.theta );
			


		}

		var verticalLookRatio = 1;

		if ( this.constrainVertical ) {

			verticalLookRatio = Math.PI / ( this.verticalMax - this.verticalMin );

		}

		this.lon += this.mouseX * actualLookSpeed;
		if( this.lookVertical ) this.lat -= this.mouseY * actualLookSpeed * verticalLookRatio;

		this.lat = Math.max( - 85, Math.min( 85, this.lat ) );
		this.phi = ( 90 - this.lat ) * Math.PI / 180;

		this.theta = this.lon * Math.PI / 180;

		if ( this.constrainVertical ) {

			this.phi = THREE.Math.mapLinear( this.phi, 0, Math.PI, this.verticalMin, this.verticalMax );

		}

    // if(this.rotateLeft||this.rotateRight){
    //   this.object.lookAt( this.targetPosition );
    //   // this.object.lookAt(new THREE.Vector3);
    // }
    
      // if(this.lookLeft)this.mouseX=-1*window.innerWidth;
      // if(this.lookRight) this.mouseX=window.innerWidth;
      // if(this.lookUp) this.mouseY=window.innerHeight;
      // if(this.lookDown) this.mouseY=-1*window.innerHeight;
      
    if(this.moveLeft||this.moveRight || this.moveForward||this.backForward || this.lookLeft || this.lookRight){
        var targetPosition = this.targetPosition;
        position = this.object.position;
        // position = this.targetPosition;
        targetPosition.x = position.x + 100 * Math.sin( this.phi ) * Math.cos( this.theta );
        // targetPosition.y = position.y + 100 * Math.cos( this.phi );
        targetPosition.y=200;
        targetPosition.z = position.z + 100 * Math.sin( this.phi ) * Math.sin( this.theta );
        
        this.targetPosition.copy(targetPosition);
        // this.object.lookAt( this.targetPosition );
    }
    
    		
    this.object.lookAt( this.targetPosition );	

	};


	this.domElement.addEventListener( 'contextmenu', function ( event ) { event.preventDefault(); }, false );

  // this.domElement.addEventListener( 'click', bind( this, this.onMouseClick ), false );
  
	// this.domElement.addEventListener( 'mousemove', bind( this, this.onMouseMove ), false );
	// this.domElement.addEventListener( 'mousedown', bind( this, this.onMouseDown ), false );
	// this.domElement.addEventListener( 'mouseup', bind( this, this.onMouseUp ), false );
	this.domElement.addEventListener( 'keydown', bind( this, this.onKeyDown ), false );
	this.domElement.addEventListener( 'keyup', bind( this, this.onKeyUp ), false );

	function bind( scope, fn ) {

		return function () {

			fn.apply( scope, arguments );

		};

	};
this.cameraInsector=function() {
	if(this.rotateRight || this.rotateLeft)
			return;
		var f_vector = new THREE.Vector3(0, 0, -1);
		var b_vector = new THREE.Vector3(0, 0, 1);
		var l_vector = new THREE.Vector3(-1, 0, 0);
		var r_vector = new THREE.Vector3(1, 0, 0);
		halfSize = 10;
		var left = new THREE.Vector3(this.object.position.x - halfSize, this.object.position.y - halfSize, this.object.position.z);
		var right = new THREE.Vector3(this.object.position.x + halfSize, this.object.position.y - halfSize, this.object.position.z);
		var front = new THREE.Vector3(this.object.position.x, this.object.position.y - halfSize, this.object.position.z + halfSize);
		var back = new THREE.Vector3(this.object.position.x, this.object.position.y - halfSize, this.object.position.z - halfSize);

		// front
		// if(this.moveForward) {
		var left_ray = new THREE.Ray(left, f_vector);
		var left_intersects = left_ray.intersectObjects(scene.children);
		if(left_intersects.length > 0 && left_intersects[0].distance < halfSize) {
			this.object.position.z = left_intersects[0].point.z + halfSize + 1;
			this.moveForwardFreeze = true;
			this.freeze = true;

			console.warn("intersected on	" + left_intersects[0].object.name + " " + left_intersects[0].object.gTypeId + " " + left_intersects[0].object.description);
			return;
		

		}
		var right_ray = new THREE.Ray(right, f_vector);
		var right_intersects = right_ray.intersectObjects(scene.children);
		if(right_intersects.length > 0 && right_intersects[0].distance < halfSize) {
			this.object.position.z = right_intersects[0].point.z + halfSize + 1;
			this.freeze = true;
			this.moveForwardFreeze = true;
			
			console.warn("intersected on	" + right_intersects[0].object.name + " " + right_intersects[0].object.gTypeId + " " + right_intersects[0].object.description);
			return;
		}

		var left_ray = new THREE.Ray(left, b_vector);
		var left_intersects = left_ray.intersectObjects(scene.children);
		if(left_intersects.length > 0 && left_intersects[0].distance < halfSize) {
			this.object.position.z = left_intersects[0].point.z - halfSize - 1;
			this.moveBackwardFreeze = true;
			this.freeze = true;


			console.warn("intersected on	" + left_intersects[0].object.name + " " + left_intersects[0].object.gTypeId + " " + left_intersects[0].object.description);
			return;
		}
		var right_ray = new THREE.Ray(right, b_vector);
		var right_intersects = right_ray.intersectObjects(scene.children);
		if(right_intersects.length > 0 && right_intersects[0].distance < halfSize) {
			this.object.position.z = right_intersects[0].point.z - halfSize - 1;
			this.moveBackwardFreeze = true;
			this.freeze = true;
			
			console.warn("intersected on	" + right_intersects[0].object.name + " " + right_intersects[0].object.gTypeId + " " + right_intersects[0].object.description);
			return;
		}

		var back_ray = new THREE.Ray(back, l_vector);
		var back_intersects = back_ray.intersectObjects(scene.children);
		if(back_intersects.length > 0 && back_intersects[0].distance < halfSize) {
			this.object.position.x = back_intersects[0].point.x + halfSize + 1;
			this.moveLeftFreeze = true;
			this.freeze = true;
			
			console.warn("intersected on	" + back_intersects[0].object.name + " " + back_intersects[0].object.gTypeId + " " + back_intersects[0].object.description);
			return;
		}
		var front_ray = new THREE.Ray(front, l_vector);
		var front_intersects = front_ray.intersectObjects(scene.children);
		if(front_intersects.length > 0 && front_intersects[0].distance < halfSize) {
			this.object.position.x = front_intersects[0].point.x + halfSize + 1;
			this.moveLeftFreeze = true;
			this.freeze = true;
			
			console.warn("intersected on	" + front_intersects[0].object.name + " " + front_intersects[0].object.gTypeId + " " + front_intersects[0].object.description);
			return;
		}

		var back_ray = new THREE.Ray(back, r_vector);
		var back_intersects = back_ray.intersectObjects(scene.children);
		if(back_intersects.length > 0 && back_intersects[0].distance < halfSize) {
			this.object.position.x = back_intersects[0].point.x - halfSize - 1;
			this.moveRightFreeze = true;
			this.freeze = true;

			console.warn("intersected on	" + back_intersects[0].object.name + " " + back_intersects[0].object.gTypeId + " " + back_intersects[0].object.description);
		}
		var front_ray = new THREE.Ray(front, r_vector);
		var front_intersects = front_ray.intersectObjects(scene.children);
		if(front_intersects.length > 0 && front_intersects[0].distance < halfSize) {
			this.object.position.x = front_intersects[0].point.x - halfSize - 1;
			this.moveRightFreeze = true;
			this.freeze = true;
			
			console.warn("intersected on	" + front_intersects[0].object.name + " " + front_intersects[0].object.gTypeId + " " + front_intersects[0].object.description);
		}
	
	}
};
